// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package gob

import (
	"bufio"
	"errors"
	"io"
	"reflect"
	"sync"
)

// tooBig提供了尺寸的健康检查；在好几个地方使用。上限
// 在32位系统上为1GB，在64位系统上为8GB，允许在没有溢出的情况下稍微增加一点
// 的空间。
const tooBig = (1 << 30) << (^uint(0) >> 62)

// 解码器管理从连接的远程端读取的类型和数据信息的接收。多个
// goroutines同时使用是安全的。
// 
// 解码器仅对解码的输入大小进行基本的健全性检查，
// 其限制是不可配置的。解码来自不可信来源的gob数据
// 时要小心。
type Decoder struct {
	mutex        sync.Mutex                              // 每个项目必须以原子方式接收
	r            io.Reader                               // 数据源
	buf          decBuffer                               // 缓冲区用于更有效地从r进行i/o 
	wireType     map[typeId]*wireType                    // 从远程ID映射到本地描述
	decoderCache map[reflect.Type]map[typeId]**decEngine // 编译引擎缓存
	ignorerCache map[typeId]**decEngine                  // 忽略对象同上
	freeList     *decoderState                           // 自由解码状态列表；避免重新分配
	countBuf     []byte                                  // 在解析消息时用于解码整数
	err          error
}

// NewDecoder返回从io读取的新解码器。读者
// 如果r不实现io。ByteReader，它将被包裹在
// bufio中。读者
func NewDecoder(r io.Reader) *Decoder {
	dec := new(Decoder)
	// 我们使用读取字节的能力作为缓冲的合理替代。
	if _, ok := r.(io.ByteReader); !ok {
		r = bufio.NewReader(r)
	}
	dec.r = r
	dec.wireType = make(map[typeId]*wireType)
	dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
	dec.ignorerCache = make(map[typeId]**decEngine)
	dec.countBuf = make([]byte, 9) // 计数可能是UINT64（不太可能！），require 9字节

	return dec
}

// recvType加载类型的定义。
func (dec *Decoder) recvType(id typeId) {
	// 我们已经见过这种类型了吗？这是一个错误
	if id < firstUserId || dec.wireType[id] != nil {
		dec.err = errors.New("gob: duplicate type received")
		return
	}

	// 类型：
	wire := new(wireType)
	dec.decodeValue(tWireType, reflect.ValueOf(wire))
	if dec.err != nil {
		return
	}
	// 记住我们见过这种类型。
	dec.wireType[id] = wire
}

var errBadCount = errors.New("invalid message length")

// recvMessage从输入中读取下一个计数分隔的项。它是编码器的反向
// 。书面信息。在EOF或读取消息时返回false。
func (dec *Decoder) recvMessage() bool {
	// 读取计数。
	nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
	if err != nil {
		dec.err = err
		return false
	}
	if nbytes >= tooBig {
		dec.err = errBadCount
		return false
	}
	dec.readMessage(int(nbytes))
	return dec.err == nil
}

// readMessage从输入中读取下一个N字节。
func (dec *Decoder) readMessage(nbytes int) {
	if dec.buf.Len() != 0 {
		// 缓冲区现在应该总是空的。
		panic("non-empty decoder buffer")
	}
	// 读取数据
	dec.buf.Size(nbytes)
	_, dec.err = io.ReadFull(dec.r, dec.buf.Bytes())
	if dec.err == io.EOF {
		dec.err = io.ErrUnexpectedEOF
	}
}

// toInt根据封送规则将编码的uint64转换为int。
func toInt(x uint64) int64 {
	i := int64(x >> 1)
	if x&1 != 0 {
		i = ^i
	}
	return i
}

func (dec *Decoder) nextInt() int64 {
	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
	if err != nil {
		dec.err = err
	}
	return toInt(n)
}

func (dec *Decoder) nextUint() uint64 {
	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
	if err != nil {
		dec.err = err
	}
	return n
}

// decodeTypeSequence解析：
// TypeSequence 
// （typedefinitiondTypedefinition*）？
// 并返回下一个值的类型id。在
// EOF处返回-1。返回时，dec.buf的剩余部分是
// 解码的值。如果这是一个接口值，
// 重置该缓冲区时可以忽略它。
func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
	firstMessage := true
	for dec.err == nil {
		if dec.buf.Len() == 0 {
			if !dec.recvMessage() {
				// 我们只能返回io。如果输入为空，则为EOF。
				// 如果我们读取了一个或多个类型规范消息，
				// 则需要遵循一条数据项消息。
				// 如果我们在那之前遇到了EOF，那么给出意外的错误。
				if !firstMessage && dec.err == io.EOF {
					dec.err = io.ErrUnexpectedEOF
				}
				break
			}
		}
		// 接收类型id。
		id := typeId(dec.nextInt())
		if id >= 0 {
			// 值如下。
			return id
		}
		// 下面是（-id）的类型定义。
		dec.recvType(-id)
		if dec.err != nil {
			break
		}
		// 当解码一个接口时，在一个类型之后，缓冲区中可能还有一个
		// DelimitedValue。跳过它的计数。
		// （或者，缓冲区为空，字节计数
		// 将被RecVMMessage吸收。）
		if dec.buf.Len() > 0 {
			if !isInterface {
				dec.err = errors.New("extra data in buffer")
				break
			}
			dec.nextUint()
		}
		firstMessage = false
	}
	return -1
}

// 解码从输入流中读取下一个值，并将其存储在由空接口值表示的数据中。
// 如果e为零，则该值将被丢弃。否则，
// 基础e的值必须是指向
// 接收的下一个数据项的正确类型的指针。
// 如果输入处于EOF，Decode返回io。EOF和
// 不修改e。
func (dec *Decoder) Decode(e any) error {
	if e == nil {
		return dec.DecodeValue(reflect.Value{})
	}
	value := reflect.ValueOf(e)
	// 如果e代表一个与指针相反的值，则答案不会返回调用方。确保它是指针。
	if value.Type().Kind() != reflect.Pointer {
		dec.err = errors.New("gob: attempt to decode into a non-pointer")
		return dec.err
	}
	return dec.DecodeValue(value)
}

// DecodeValue从输入流中读取下一个值。
// 如果v是零反射。值（v.Kind（）==无效），DecodeValue放弃该值。
// 否则，它将值存储到v中。在这种情况下，v必须表示
// 一个指向数据的非零指针，或者是一个可赋值的反射。Value（v.CanSet（））
// 如果输入处于EOF，DecodeValue返回io。EOF和
// 不修改v.
func (dec *Decoder) DecodeValue(v reflect.Value) error {
	if v.IsValid() {
		if v.Kind() == reflect.Pointer && !v.IsNil() {
			// 没关系，我们将通过指针存储。
		} else if !v.CanSet() {
			return errors.New("gob: DecodeValue of unassignable value")
		}
	}
	// 确保我们是单线程的。
	dec.mutex.Lock()
	defer dec.mutex.Unlock()

	dec.buf.Reset() // 以防上一次调用的数据延迟。
	dec.err = nil
	id := dec.decodeTypeSequence(false)
	if dec.err == nil {
		dec.decodeValue(id, v)
	}
	return dec.err
}

// 如果调试。go被编译到程序中，debugFunc通过调用该文件的Debug函数打印一个可读的
// 表示从r读取的gob数据。
// 否则为零。
var debugFunc func(io.Reader)
